﻿using System.Collections;
using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class MetadataClass : MetadataLabeledObject, IReadOnlyList<MetadataField>
{
    private SyntaxList<MetadataField>? _fields;

    internal MetadataClass(SyntaxToken fieldsKeywordToken, SyntaxNode? parent) :
        base(SyntaxKinds.MetadataClass,
            fieldsKeywordToken,
            NodeConverter.ToIdentifier(fieldsKeywordToken),
            parent)
    {
    }


    protected override bool WithoutNameIdentifier => true;

    public int Count => _fields?.Count ?? 0;

    public MetadataField this[int index] =>
        _fields == null
            ? throw new IndexOutOfRangeException(nameof(index))
            : _fields[index];


    public IEnumerator<MetadataField> GetEnumerator()
    {
        return _fields?.GetEnumerator() ??
               Enumerable.Empty<MetadataField>().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    public void AddField(MetadataField field)
    {
        AddChildMember(ref _fields, field);
    }


    public MetadataField? GetField(string fieldName)
    {
        return _fields?.Find(f => f.Name.Equals(fieldName, StringComparison.OrdinalIgnoreCase));
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        base.AcceptVisitor(visitor);
        AcceptList(visitor, _fields);
    }
}


public static partial class NodeFactory
{
    public static MetadataClass CreateMetadataClass(SyntaxNode? parent, SyntaxToken fieldsKeyword,
        IEnumerable<MetadataField>? fields)
    {
        Debug.Assert(fieldsKeyword.IsNode(SyntaxKinds.FieldsKeywordToken));
        MetadataClass metadataClass = new(fieldsKeyword, parent);
        if (fields != null)
        {
            foreach (MetadataField field in fields)
            {
                metadataClass.AddField(field);
            }
        }

        return metadataClass;
    }
}